package com.chapter.sample.redis.iomultiplex.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.concurrent.TimeUnit;

public class RedisServerNIO {
    static ArrayList<SocketChannel> socketList = new ArrayList<>();
    static ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

    public static void main(String[] args) throws IOException, InterruptedException {
        System.out.println("-------------RedisServerNIO 启动等待中-----------------");
        ServerSocketChannel serverSocket = ServerSocketChannel.open();
        serverSocket.bind(new InetSocketAddress("127.0.0.1", 6389));
        serverSocket.configureBlocking(false);

        /**
         * select 其实就是把NIO中用户态要遍历的fd数组（我们的每一个socket连接，安装进ArrayList里面的那个）拷贝到内核态，
         * 让内核态来遍历，因为用户态判断socket是否有数据还是要调用内核态的，所有拷贝到内核态后，
         * 这样遍历判断的时候就不用一直用户态和内核态频繁切换了
         */
        while (true) {
            for (SocketChannel element : socketList) {
                int read = element.read(byteBuffer);
                if (read > 0) {
                    System.out.println("------读区数据：" + read);
                    byteBuffer.flip();
                    byte[] bytes = new byte[read];
                    byteBuffer.get(bytes);
                    System.out.println(new String(bytes));
                    byteBuffer.clear();
                }
                TimeUnit.SECONDS.sleep(1);
            }

            SocketChannel socketChannel = serverSocket.accept();
            if (socketChannel != null) {
                System.out.println("------------成功连接：");
                socketChannel.configureBlocking(false);//设置为非阻塞模式
                socketList.add(socketChannel);
                System.out.println("------------socketList size：" + socketList.size());
            }
        }
    }
}
